/* WinKawaks三国志2脚本(UTF-8 with BOM),一键下上A,一键马上挑人,一键后跳踢,一键滑步升龙,一键暂停,一键切换静音
  By setycyas @2022-10-18
*/

SendMode Input ; Recommended for new scripts due to its superior speed and reliability.

/* 调用自制的库 
*/ { ;不缩进块
#Include D:\software\AutoHotkey\MyAHK\MyAhkModules\MyKey.ahk ;按键相关库,所有函数导出到MyKey对象中
#Include D:\software\AutoHotkey\MyAHK\MyAhkModules\WinKawaksCommon.ahk ;WinKawaks的一般库,函数导出到WinKawaksCommon对象
} ;不缩进块

/* 全局变量GV,包含各种库函数引用和常量定义
*/ { ;不缩进块
GV := Object()
;库函数引用
GV.LIB := {"MyKey": MyKey, "WinKawaksCommon": WinKawaksCommon}
;键定义
GV.KEYS := {"punch": "d", "jump": "e"}
;枚举量,暂时是一般模式和马战模式,区别是左右技能按键是赵云的滑步升龙还是马上挑人,默认是马战模式因为其他人不需要用滑步升龙
;TOGGLE_MODE不是一种模式,是在模式变换函数中的参数,表示切换
GV.ENUM := {"NORMAL_MODE": 0, "HORSE_MODE": 1, "TOGGLE_MODE": 2}
GV.mode := GV.ENUM.HORSE_MODE ;当前模式
;从Gui中读取的全局变量,需要在makeData()函数中制作
GV.duDelay1 := 0 ;技能下上拳的延时1,定义为按下↓结束到按下↑的毫秒数,此定义与Gui接受的变量不同
GV.duDelay2 := 0 ;技能下上拳的延时2,定义为按下↑开始到按下a的毫秒数
GV.keyDuration := 0 ;按键持续时间
GV.horseDelay := 0 ;马上挑人技能延时,定义为按下↑a并放手后到按下方向键的毫秒数,测试发现魏延赵云50,关羽100,张飞150
GV.backJumpDelay := 0 ;后跳踢延时,定义为按下跳键后再按后键的毫秒数

} ;不缩进块

/* 接收Gui输入的全局变量,以G=gui 开头
*/ { ;不缩进块
GduDelay1 := 90 ;120 ;技能下上拳的延时1,定义为按下↓开始到按下↑的毫秒数
GduDelay2 := 80 ;100 ;技能下上拳的延时2,定义为按下↑开始到按下a的毫秒数
GkeyDuration := 70 ;80 ;按键持续时间,怀疑对这个参数最敏感
GhorseDelay := 50 ;马上挑人技能延时,定义为按下↑a并放手后到按下方向键的毫秒数,测试发现魏延赵云50,关羽100
GbackJumpDelay := 50 ;后跳踢延时,定义为按下跳键后再按后键的毫秒数,测试发现魏延赵云50,关羽什么数字都没把握
} ;不缩进块

/* 自定义函数
*/ { ;不缩进块

;缩短MyKey.press函数名称
press(key, pressDuration := 100){
  global GV
  return GV.LIB.MyKey.press.Call(key, pressDuration)
}

;缩短MyKey的pressKeys函数名
pressKeys(keys, delays, duration := 50){
  global GV
  return GV.LIB.MyKey.pressKeys.Call(keys, delays, duration)
}

;从Gui获取的数据制作全局变量数据
makeData(){
  global GV
  global GduDelay1
  global GduDelay2
  global GkeyDuration
  global GhorseDelay 
  global GbackJumpDelay
  
  GV.duDelay1 := GduDelay1-GkeyDuration
  GV.duDelay2 := GduDelay2
  GV.keyDuration := GkeyDuration
  GV.horseDelay := GhorseDelay 
  GV.backJumpDelay := GbackJumpDelay
}

;切换模式,mode参数是GV.ENUM中MODE的其中一个
changeMode(mode){
  global GV
  
  ;令GV.mode获得正确的模式
  if (mode == GV.ENUM.TOOGLE_MODE) {
    if (GV.mode == GV.ENUM.NORMAL_MODE) {
      GV.mode := GV.ENUM.HORSE_MODE
    } else {
      GV.mode := GV.ENUM.NORMAL_MODE
    }
  } else {
    GV.mode := mode
  }
  ;在状态栏显示当前模式并转换颜色
  if (GV.mode == GV.ENUM.NORMAL_MODE) {
    SB_SetText("一般模式")
    Gui, Color, 00A0D8
  } else if (GV.mode == GV.ENUM.HORSE_MODE) {
    SB_SetText("马战模式")
    Gui, Color, B87040
  }
}

;↓↑A技能,按下后立即按方向键可使出赵云的带方向升龙剑
duSkill(){
  global GV
  
  press("down", GV.keyDuration)
  sleep, % GV.duDelay1
  pressKeys(["up", GV.KEYS.punch], [GV.duDelay2], GV.keyDuration)
  return
}

;↓→↑A技能,可带方向
dfuSkill(direction := "left"){
  global GV
  
  if (direction != "left")
    direction := "right"
  press("down", GV.keyDuration)
  sleep, % GV.duDelay1
  pressKeys([direction, "up", GV.KEYS.punch], [50, GV.duDelay2], GV.keyDuration)
  return
}

;↑A+方向,马上技能
u1HorseSkill(direction := "left"){
  global GV
  
  if (direction != "left")
    direction := "right"
  pressKeys(["up", GV.KEYS.punch], [50], GV.keyDuration)
  sleep, % GV.horseDelay
  press(direction, GV.keyDuration)
  return
}

;后跳踢,direction定义的是跳跃方向而不是面向方向!
backJumpKick(direction := "left"){
  global GV
  
  if (direction != "left")
    direction := "right"
  pressKeys([GV.KEYS.jump, direction], [GV.backJumpDelay], GV.keyDuration)
  sleep, 50
  press(GV.KEYS.punch, GV.keyDuration)
}

} ;不缩进块

/* 加入Gui并返回
*/ { ;不缩进块
Gui, Add, Tab3,w230, params|hotkeys ;顺便测试标签页分组,下面直接加入的组件属于当前标签页
Gui, Tab, 1 ;表示以下组件属于第1个标签页,可省略
Gui, Add, Text, x+20 y+20, ↓↑a 延时1： ;
Gui, Add, Edit, xp+80 yp-3 w60 vGduDelay1, %GduDelay1% ;技能↓↑A延时1
Gui, Add, Text, xp-80 yp+30, ↓↑a 延时2： ;
Gui, Add, Edit, xp+80 yp-3 w60 vGduDelay2, %GduDelay2% ;技能↓↑A延时2
Gui, Add, Text, xp-80 yp+30, 按键持续时间： ;
Gui, Add, Edit, xp+80 yp-3 w60 vGkeyDuration, %GkeyDuration% ;按键持续时间
Gui, Add, Text, xp-80 yp+30, 马上挑人延时： ;
Gui, Add, Edit, xp+80 yp-3 w60 vGhorseDelay, %GhorseDelay% ;马上挑人技能延时
Gui, Add, Text, xp-80 yp+30, 后跳踢延时： ;
Gui, Add, Edit, xp+80 yp-3 w60 vGbackJumpDelay, %GbackJumpDelay% ;后跳踢延时
Gui, Tab, 2 ;表示以下组件属于第2个标签页
Gui, Add, Text, ,s - ↓↑a
Gui, Add, Text, ,q - 马战向左挑人 or 赵云左滑步升龙
Gui, Add, Text, ,r - 马战向右挑人 or 赵云右滑步升龙
Gui, Add, Text, ,RControl - 切换模式(马战或一般)
;Gui, Add, Text, ,2`,3 - 后跳踢`,分别为面向左右
Gui, Add, Text, ,numpad0 - 切换暂停与开始
Gui, Add, Text, ,numpad1 - 切换静音
Gui, Tab ;表示下面组件不再属于标签页
Gui, Add, Button, , Submit_ ;提交
Gui, Add, Button, xp+120, Exit ;结束app
Gui, Add, StatusBar
Gui, Show, w250h260, WinKawaks - 三国志2
changeMode(GV.mode)
makeData()
return
} ;不缩进块

/* Gui响应
*/ { ;不缩进块
ButtonSubmit_: 
Gui, Submit,NoHide ; 保存用户输入后每个控件的数据,NoHide可以在提交数据后保持窗体显示
makeData()
MsgBox, You have submit your changes!
return

ButtonExit:
GuiClose:
ExitApp
return
} ;不缩进块

/* 快捷键
*/ { ;不缩进块
#IfWinActive, ahk_exe WinKawaks.exe

;s键,↓↑a必杀
~s::
{
  duSkill()
  return
}

;q键,马战模式是向左挑人;一般模式是面向左边的赵云滑步升龙
~q::
{
  if (GV.mode == GV.ENUM.HORSE_MODE) {
    u1HorseSkill("left")
  } else if (GV.mode == GV.ENUM.NORMAL_MODE) {
    dfuSkill("left")
  }
  return
}

;r键,马战模式是向右挑人,;一般模式是面向右边的赵云滑步升龙
~r::
{
  if (GV.mode == GV.ENUM.HORSE_MODE) {
    u1HorseSkill("right")
  } else if (GV.mode == GV.ENUM.NORMAL_MODE) {
    dfuSkill("right")
  }
  return
}

/* 后跳踢,后来发现用宏也可以实现,暂时取消,但无论是宏还是脚本,关羽都不行,用脚本还有少量成功率,宏是直接不行
;2,3键,对应面向左,右的后跳踢
~2::
{
  backJumpKick("right")
  return
}
~3::
{
  backJumpKick("left")
  return
}
*/


;numpad0暂停或开始
~numpad0::
{
  GV.LIB.WinKawaksCommon.pauseToggle.Call()
  return
}

;numpad1切换静音状态
~numpad1::
{
  GV.LIB.WinKawaksCommon.soundToggle.Call()
  return
}

;右ctrl,转换马战与一般模式
~RControl::
{
  changeMode(GV.ENUM.TOOGLE_MODE)
  return
}

#IfWinActive
} ;不缩进块